<template>
  <div class="hashRank">
    <!-- 标题 -->
    <div class="hashRank-title items-center">
      <div class="hashRank-title-value items-center">
        <div>
          {{ $t("lotteryMoney.jyhxtop5") }}
          {{ $t("lotteryMoney.hxzhws").split("xxx")[0] }}
          <span class="hashRank-title-nums">
            {{ hashScoreLength }}
          </span>
          {{ $t("lotteryMoney.hxzhws").split("xxx")[1] }}
        </div>

        <!-- 提示信息 -->
        <div class="tabelheader-popover">
          <van-popover
            class="popover"
            placement="bottom-end"
            :offset="[15, 11]"
          >
            <div class="popover-alert">
              {{ $t("lotteryMoney.hxdesctext") }}
            </div>
            <template #reference>
              <img class="popover-img" src="/image/wh2-icon.svg" />
            </template>
          </van-popover>
        </div>
      </div>
    </div>
    <!-- 表头 -->
    <div class="tabelheader items-center">
      <div class="tabelheader-user">{{ $t("lotteryMoney.user") }}</div>
      <div class="tabelheader-team">{{ $t("lotteryMoney.team") }}</div>
      <div class="tabelheader-jyhx">
        {{ $t("lotteryMoney.jyhx") }}
      </div>
      <!-- <div class="tabelheader-hxvalue">{{ $t("lotteryMoney.hxvalue") }}</div> -->
    </div>
    <div v-if="!loading && slides.length > 0">
      <transition-group name="swap" tag="div">
        <!-- 列表 -->
        <div
          v-for="(item, index) in slides"
          class="item-animation item-bg-flex"
          :class="{
            'item-bg': index % 2 == 0,
          }"
          :key="item.transactionHash"
          :style="{ order: index }"
        >
          <div class="item items-center">
            <div class="items-center">
              <div class="item-rank">{{ index + 2 }}</div>
              <ImgNuxt
                class="item-avatar"
                isHttp
                :placeholder="file.avatarDefault"
                :src="item.avatar"
              />
              <div class="item-nickname">
                {{ item.nickname || "--" }}
              </div>
            </div>

            <div class="item-team">{{ item.teamName || "--" }}</div>
            <div
              class="item-hax"
              @click.stop="showPopupHash(item.transactionHash)"
            >
              {{ item.transactionHash.substring(0, 4) }}...
              <span class="item-hax-value">{{
                item.transactionHash.substring(
                  item.transactionHash.length - hashScoreLengthCur,
                  item.transactionHash.length
                )
              }}</span>
            </div>

            <!-- <div class="item-btn">
                {{ item.hashScore }}
              </div> -->
          </div>
        </div>
      </transition-group>
    </div>
    <div v-else>
      <div class="hashRank-notdata items-center">
        <img
          class="hashRank-notdata-img"
          src="/image/lotterymoney/zwsj-icon.svg"
        />
        <div class="hashRank-notdata-text">
          {{ $t("lotteryMoney.zwsj") }}
        </div>
      </div>
    </div>
    <!-- 哈希值弹窗 -->
    <HashValuePopup v-model:show="isShowHash" :hashText="hashText" />
  </div>
</template>
<script setup lang="ts" name="hashRank">
import { onMounted } from "vue";
import { getOssFileUrl, navigateI18nTo } from "@/utils";
import { useEventBus } from "@vueuse/core";
import { topHashScoreRecord } from "@/api/lottery";
import HashValuePopup from "./hash-value-popup.vue";
import { useLotteryMoneyStore } from "~~/store/modules/lottery-money";

const props = withDefaults(
  defineProps<{
    activitytStatus: number;
    hashScoreLength: number;
  }>(),
  {
    activitytStatus: 1, //   1 未开始  2 进行中  3 已结束
    hashScoreLength: 1,
  }
);

const emit = defineEmits(["initDone", "update:centerindex", "change"]);
const { t } = useI18n();
const lotteryMoneyStore = useLotteryMoneyStore();

// 资源
const file = getOssFileUrl({
  avatarDefault: "/image/avatar-default.png",
});

// 正在加载
const loading = ref(false);
// 列表数据
const slides = ref([]);

// 定时器-通知
const moneyInterval = useEventBus("lottery-money-interval-emit");
let moneyIntervalEmit: any = null;

// socket 消息推送
let hashScoreArr: any = [];
const openCardSocket = useEventBus("lotteryMoney-socket-bdcLotteryOpenCard");
let openCardSocketOn = openCardSocket.on((val: any) => {
  // 1. pk 位数升级的场景,直接替换2~4名
  if (val.top4 && val.top4.length > 0) {
    slides.value = val.top4.slice(1, 4).map((element: any) => {
      if (element.teamConfigId == 1) {
        element.teamName = t("lotteryMoney.redTeam");
      } else if (element.teamConfigId == 2) {
        element.teamName = t("lotteryMoney.yellowTeam");
      } else if (element.teamConfigId == 3) {
        element.teamName = t("lotteryMoney.blueTeam");
      }
      return element;
    });
  }
});

// 数据融合:公共处理逻辑
const dataFusion = (res: any, isWtach = false) => {
  loading.value = false;
  if (
    (res && props.activitytStatus == 2) ||
    props.activitytStatus == 7 ||
    props.activitytStatus == 8
  ) {
    if (!lotteryMoneyStore.$state.isDoneTop4list) {
      lotteryMoneyStore.$patch((state) => {
        state.isDoneTop4list = state.isUseSocketing && true;
      });
    }

    if (res.topHashList && res.topHashList.length > 0) {
      res.topHashList = res.topHashList.map((element: any) => {
        if (element.teamConfigId == 1) {
          element.teamName = t("lotteryMoney.redTeam");
        } else if (element.teamConfigId == 2) {
          element.teamName = t("lotteryMoney.yellowTeam");
        } else if (element.teamConfigId == 3) {
          element.teamName = t("lotteryMoney.blueTeam");
        }
        return element;
      });

      // zhjdebugger
      // res.topHashList = res.topHashList.splice(0, 10);
      // 初始化,或者覆盖原始 top4 数据
      if (!isWtach) {
        // console.log("--初始化,或者覆盖原始 top4 数据,pkTop4Arr变更");
        lotteryMoneyStore.$patch((state) => {
          state.pkTop4Arr = res.topHashList;
        });
      }

      // 保存: 第一名信息
      firstRank.value = res.topHashList[0];
      // 只要  2, 3,4 三名

      let rank234 = res.topHashList.slice(1, 4);

      let isSort = false;
      if (hashScoreArr.length == 3) {
        // 检测得分,是否不一样
        rank234.forEach((element: any, index: number) => {
          element.order = index;
          if (!hashScoreArr.includes(element.hashScore)) {
            isSort = true;
          }
        });
        if (!isSort) {
          let soreArr_l = rank234.map((e: any) => {
            return e.hashScore || 0;
          });
          // 去重
          soreArr_l = [...new Set(soreArr_l)];
          // 得分一样
          if (soreArr_l.length < 3) {
            isSort = true;
          }
          // 不一样不处理
        }
      } else {
        isSort = true;
      }

      // console.log("是否需要排序?", isSort);

      if (isSort) {
        loading.value = true;

        nextTick(() => {
          // 按时间顺序打乱一次
          if (hashScoreArr.length == 3) {
            let oldArr: any = [];
            let newArr: any = [];
            rank234.forEach((element: any) => {
              if (hashScoreArr.includes(element.hashScore)) {
                oldArr.push(element);
              } else {
                newArr.push(element);
              }
            });
            rank234 = oldArr.concat(newArr);
          }

          // 赋值数据源
          // slides.value = rank234.slice(0, 5);
          slides.value = rank234.map((element: any) => {
            if (element.teamConfigId == 1) {
              element.teamName = t("lotteryMoney.redTeam");
            } else if (element.teamConfigId == 2) {
              element.teamName = t("lotteryMoney.yellowTeam");
            } else if (element.teamConfigId == 3) {
              element.teamName = t("lotteryMoney.blueTeam");
            }
            return element;
          });
          // 展示乱序的元素.
          loading.value = false;
          // console.log("排序前的顺序:", slides.value);
          setTimeout(() => {
            startBubbleSort();
          }, 600);
        });
      }
    }
  }
};
// 监听 pkTop4Arr 的变化,变化了就开始做动画,变顺序
const pkTop4ArrWatch = watch(
  () => lotteryMoneyStore.$state.pkTop4Arr,
  (newVal, oldVal) => {
    hashScoreArr = [];
    if (slides.value.length == 3) {
      hashScoreArr = slides.value.map((e) => {
        return e.hashScore || 0;
      });
    }

    if (newVal && newVal.length > 0) {
      // console.log(newVal, "2---2", oldVal);
      dataFusion({ topHashList: newVal }, true);
    }
  }
  // {
  //   immediate: true,
  //   deep: true,
  // }
);

// 排序
const currentIndices = ref([]);
let isSorting = false;
const swap = (i, j) => {
  return new Promise((resolve) => {
    [slides.value[i], slides.value[j]] = [slides.value[j], slides.value[i]];
    setTimeout(resolve, 500); // 与 CSS 动画时间匹配
  });
};

const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};

// 字符串: a > b : 1  a == b : 0  a < b : -1
const strSpecificSize = (a: string, b: string) => {
  if (!a || !b) return false;
  if (a.length >= b.length) {
    if (a.length > b.length) {
      return 1;
    } else {
      return a > b ? 1 : -1; // 长度相等
    }
  }
  return -1;
};

// 排序算法
const startBubbleSort = async () => {
  if (isSorting) return;
  isSorting = true;

  let n = slides.value.length;
  for (let i = 1; i < n; i++) {
    let e = slides.value[i];
    let j = i - 1;
    // hashScore 从大到小; 相等的场景根据接口返回的顺序来排
    while (
      j >= 0 &&
      (strSpecificSize(slides.value[j].hashScore, e.hashScore) == -1 ||
        (slides.value[j].hashScore == e.hashScore &&
          slides.value[j].order > e.order))
    ) {
      currentIndices.value = [j, j + 1];
      await swap(j + 1, j);
      j = j - 1;
    }
    slides.value[j + 1] = e;
    await sleep(500); // 延迟以显示动画
  }
  currentIndices.value = [];
  isSorting = false;
};

// 自己下注成功通知,刷新数据
const refreshTop4 = useEventBus("lottery-money-refresh-top4");
refreshTop4.on(() => {
  topHashScoreRecordRequest();
});
/**
 * @description: 获取下注列表: 接口返回的数据,最新的在数组第一条的位置
 * 1. 接口获取的数据,按照最近 5 分钟时间过滤出最近的 50 条,不够则获取最近的 5 条
 */

const topHashScoreRecordRequest = () => {
  // 是否需要轮询
  if (!lotteryMoneyStore.isNeedPolling) return;
  //
  hashScoreArr = [];
  if (slides.value.length == 3) {
    hashScoreArr = slides.value.map((e) => {
      return e.hashScore || 0;
    });
  }
  topHashScoreRecord({ limit: 4 }).then((res) => {
    dataFusion(res);
  });
};

/******************************* pk 升级 *******************************/
// 获取第一名信息
const firstRank = ref(null);
// 当前是几位 PK
const hashScoreLengthCur = ref(props.hashScoreLength);
// 上一次 是几位 PK
const hashScoreLengthLast = ref(props.hashScoreLength);
const pkNumsWatch = watch(
  () => props.hashScoreLength,
  (newVal, oldVal) => {
    if (newVal != oldVal) {
      hashScoreLengthCur.value = newVal;
      // console.log(newVal, "-pk 升级-", hashScoreLengthCur.value);
      setTimeout(() => {
        hashScoreLengthLast.value = newVal;
      }, 15600);
    }
  }
);

onMounted(() => {
  // if (!moneyIntervalEmit) {
  //   moneyIntervalEmit = moneyInterval.on((val: any) => {
  // console.log( "vertical-swipe-定时器", slides.value.length);
  // if (
  //   props.activitytStatus == 2 ||
  //   props.activitytStatus == 7 ||
  //   props.activitytStatus == 8
  // ) {
  // 1.1 每隔 3 秒 更新一次
  // if (val % 15000 > 14000 || val % 15000 == 0) {
  //   topHashScoreRecordRequest();
  // }
  // }
  // });
  // }

  // 先获取一次数据
  if (
    props.activitytStatus == 2 ||
    props.activitytStatus == 7 ||
    props.activitytStatus == 8
  ) {
    topHashScoreRecordRequest();
  }
});

onBeforeUnmount(() => {
  moneyIntervalEmit && moneyIntervalEmit();
  pkNumsWatch && pkNumsWatch();
  openCardSocketOn && openCardSocketOn();
  pkTop4ArrWatch && pkTop4ArrWatch();
});

/**
 * @description: 展示哈希弹窗
 * @param {*} val
 */
const isShowHash = ref(false);
const hashText = ref("");
const showPopupHash = (val: string) => {
  if (val) {
    hashText.value = val;
    isShowHash.value = true;
  }
};
</script>
<style lang="scss" scoped>
.skeleton {
  height: 163 * 2px;
  width: 100vw;
}
.upgrade {
  justify-content: center;
  flex-direction: column;
  width: 100%;
  height: 0;
  opacity: 0;

  background: linear-gradient(
    90deg,
    rgba(0, 123, 255, 0) 0%,
    rgba(0, 123, 255, 0.25) 49.99%,
    rgba(0, 123, 255, 0) 100%
  );
  transition: 0.5s;
  &-height {
    height: 88 * 2px;
    opacity: 1;
    padding: 10 * 2px 0;
  }
  &-title {
    font-size: 13 * 2px;
    color: #007bff;
    font-weight: 590;
  }
  &-center {
    position: relative;
    margin: 6 * 2px 0;
    justify-content: center;
    &-item {
      min-width: 100 * 2px;
      padding: 2 * 2px 0;
      border-radius: 4 * 2px;
      background-color: #fff;
      border: 1px solid #007bff;

      &-text {
        text-align: center;
        color: #000;
        font-size: 11 * 2px;
        font-weight: 400;
      }

      &-value {
        margin-left: -3 * 2px;
        color: #007bff;
        font-size: 14 * 2px;
        font-weight: 510;
      }
    }
    &-icon {
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      width: 22 * 2px;
      height: 22 * 2px;
    }
  }
  &-footer {
    font-size: 12 * 2px;
    color: #002853;
    font-weight: 400;
    &-value {
      color: #007bff;
      font-size: 12 * 2px;
      font-weight: 590;
    }
  }
}

.hashRank {
  width: 100%;
  min-height: 150 * 2px;
  // padding-bottom: 10 * 2px;
  &-title {
    position: relative;
    justify-content: center;
    &-value {
      padding: 4 * 2px 12 * 2px;
      font-size: 13 * 2px;
      color: #fff;
      border-radius: 4 * 2px 4 * 2px 0px 0px;
      font-weight: 590;
      background: linear-gradient(90deg, #007bff 0.07%, #00b2ff 99.93%);
    }
    &-nums {
      margin: 0 6 * 2px;
      padding: 1 * 2px 6 * 2px;
      border-radius: 3 * 2px;
      background: rgba(255, 255, 255, 0.8);
      color: #007bff;
      font-size: 13 * 2px;
      font-weight: 590;
    }
  }

  &-notdata {
    min-height: 120 * 2px;
    flex-direction: column;
    justify-content: center;
    &-text {
      text-align: center;
      font-size: 14 * 2px;
      color: #999da7;
    }
    &-img {
      margin-bottom: 8 * 2px;
      width: 50 * 2px;
    }
  }
  &-record {
    position: absolute;
    top: 0;
    right: 8 * 2px;
    padding: 6.5 * 2px 0;
    color: #2a91ff;
    font-size: 10 * 2px;
    font-weight: 600;
  }
}

.tabelheader {
  position: relative;
  justify-content: space-around;
  text-align: center;
  font-size: 11 * 2px;
  font-weight: 590;
  color: #999da7;
  height: 24 * 2px;
  background-color: #f0f3fa;
  &-user {
    position: absolute;
    left: 90px;
    text-align: left;
  }
  &-team {
    position: absolute;
    left: 340px;
    width: 50 * 2px;
    text-align: left;
  }
  &-jyhx {
    position: absolute;
    left: 538px;
    width: 70 * 2px;
    text-align: right;
  }

  &-hxvalue {
    text-align: left;
    width: 102 * 2px;
  }
  &-popover {
    margin-left: -0.5 * 2px;
  }
}

.item {
  position: relative;
  justify-content: space-between;
  // margin-bottom: 10 * 2px;
  width: 100%;
  padding: 0 10 * 2px;
  &-bg {
    // background: linear-gradient(
    //   90deg,
    //   rgba(255, 255, 255, 1) 0%,
    //   #badafe 50%,
    //   rgba(255, 255, 255, 1) 100%
    // );
    background: linear-gradient(
      90deg,
      rgba(235, 244, 255, 0) 0%,
      #ebf4ff 49.5%,
      rgba(235, 244, 255, 0) 100%
    );
    border-radius: 4 * 2px;
    &-flex {
      display: flex !important;
      align-items: center;
      padding: 6 * 2px 0;
      transition: height 0.5s, transform 0.5s;
    }
  }
  &-first {
    border-radius: 0px 0px 4 * 2px 4 * 2px;
    border: 1px solid rgba(0, 0, 0, 0.1);
    background: linear-gradient(90deg, #cce5ff 50%, #ccf6ff 100%);
  }
  &-rank {
    width: 14 * 2px;
    height: 14 * 2px;
    margin-right: 20 * 2px;
    color: #007bff;
    font-size: 12 * 2px;
    font-weight: 590;
  }

  &-avatar {
    width: 18 * 2px;
    height: 18 * 2px;
    min-height: 18 * 2px;
    border-radius: 100px;
    overflow: hidden;
    margin-right: 4 * 2px;
  }
  &-hax {
    white-space: nowrap;
    text-wrap: nowrap;white-space: nowrap;
    color: #141924;
    width: 90 * 2px;
    font-size: 12 * 2px;
    text-align: right;
    &-value {
      margin-left: -2 * 2px;
      color: #007bff;
      font-weight: 600;
      font-size: 14 * 2px;
    }
  }
  &-nickname {
    @include multi-line-omit(1);
    min-width: 78 * 2px;
    max-width: 78 * 2px;
    color: #141924;
    font-size: 12 * 2px;
    text-align: left;
  }
  &-team {
    text-align: left;
    width: 50 * 2px;
    color: #141924;
    font-size: 12 * 2px;
  }

  &-btn {
    text-align: center;
    width: 68 * 2px;
    padding: 3 * 2px 6 * 2px;
    border-radius: 3 * 2px;
    text-align: center;
    color: #007bff;
    font-weight: 590;
    font-size: 12 * 2px;
  }
}
.item-animation {
  transition: height 0.5s, transform 0.5s;
}

.swap-enter-active,
.swap-leave-active {
  transition: transform 0.5s;
}
.popover {
  &-img {
    margin-left: 4 * 2px;
    width: 15 * 2px;
    height: 15 * 2px;
  }
  &-alert {
    max-width: 78vw;
    padding: 6 * 2px 12 * 2px;
    color: #fff;
    font-size: 11 * 2px;
    white-space: pre-wrap;
    background: rgba(10, 31, 106, 0.4) !important;
    backdrop-filter: blur(10px);
    border-radius: 6 * 2px;
    overflow: hidden;
  }
}
</style>
<style lang="scss">
.popover {
  .van-popover__content {
    background: transparent !important;
  }
  .van-popover__arrow {
    color: rgba(10, 31, 106, 0.4) !important;
    border-bottom-color: rgba(10, 31, 106, 0.4) !important;
    backdrop-filter: blur(10px);
  }
}
</style>
